Block diagram ของฝั่งควบคุมระดับน้ำ
Code Microcontroller (Level)
#include #include #include
#define NTIMER 4 //loop1 sw reading //loop2 adc & equations //loop3 7segment //loop4 water-filling check volatile char TmrEnb[NTIMER] = {1, 1, 1, 1}; volatile char TmrMod[NTIMER] = {1, 1, 1, 1}; volatile int TmrRel[NTIMER] = {100,10, 4, 500}; //0.5ms volatile int TmrCnt[NTIMER] = {100,10, 4, 500}; volatile char TmrRdy[NTIMER] = {0, 0, 0, 0}; volatile char TmrErr[NTIMER] = {0, 0, 0, 0};
void Hardware_init(void); void ADC_init(void); void Timer1_init(void);
int main(void) { unsigned char segment_ndot[10] = {0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90}; unsigned char anaout[51] = {0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A,0x0A, 0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D, 0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32}; unsigned int ana=10; unsigned int adc[50];int adcn=0;int w=0; unsigned int avradc=0; unsigned char bcd[3]; unsigned char flag= 0x00; //unsigned char buffer= 0x00; int i=0,j =0; float set_level=0.000000000; float real_level=0; float dif_level=0; unsigned long int level; Hardware_init(); ADC_init(); Timer1_init();
sei(); while(1) { cli(); if(TmrRdy[0] == 1) { TmrRdy[0] = 0; sei();
if(((PINA&0x10)==0x10)&&(flag == 0x00)) { flag = 0x01; } else if(((PINA&0x10)==0x00)&&(flag == 0x01)) { flag = 0x00; set_level=3.00000; } else if(((PINA&0x20)==0x20)&&(flag == 0x00)) { flag = 0x02; } else if(((PINA&0x20)==0x00)&&(flag == 0x02)) { flag = 0x00; set_level=4.00000; } else if(((PINA&0x40)==0x40)&&(flag == 0x00)) { flag = 0x04; } else if(((PINA&0x40)==0x00)&&(flag == 0x04)) { flag = 0x00; set_level=0.0000; } else{ } } else if(TmrRdy[1] == 1) { TmrRdy[1]=0;
sei();
ADMUX = 0x41; ADCSRA |= (1<
while(!(ADCSRA&(1< { adc[adcn] = ADCW; } adcn++; //////////////////////////////////////////// if(adcn==50){adcn=0;} else{} //////////////////////////////////////////// if(adcn==0) { for(w=0;w<50;w++) { avradc = avradc + adc[w]; } avradc = avradc/50; } else{} //////////////////////////////////////////// if((avradc>=196)&&(avradc<=1024)) { real_level = (float) (((0.0139508)*avradc)-2.7428388); } else if(avradc<106) { real_level = 0; } /*else { real_level =0; } //////////////////////////////////////////// */ } else if(TmrRdy[2] == 1) { TmrRdy[2] = 0; sei(); level = (unsigned long int)(real_level*10); for(i = 0; i < 3; i++) { bcd[i] = level%10; level = level/10; } if(j == 0) { PORTB = 0b00000100; PORTB |= segment_ndot[bcd[0]]; j++; } else if(j == 1) { PORTB = 0b00001010; PORTB |= segment_ndot[bcd[1]]; j++; } else if(j == 2) { PORTB = 0b00000001; PORTB |= segment_ndot[bcd[2]]; j=0; } else{} } else if(TmrRdy[3] == 1) { TmrRdy[3] = 0; sei(); dif_level = (float)(set_level - real_level); if(set_level==3.000) { //////////////////////////////////////////// if((dif_level>0.5000)&&(dif_level<=3.0000)) { ana = (unsigned int)((10.5*dif_level)+10); } else if(dif_level>3.0000) { ana = 41; } else if(dif_level<=0) { ana = 10;set_level=0; } else{ } } else if(set_level==4.000) { if((dif_level>0)&&(dif_level<=1.000)) { ana = (unsigned int)((17*dif_level)+10); } else if(dif_level>1.00) { ana = 27; } else if(dif_level<=0) { ana = 10;set_level=0; } else{ } } else { ana =10; } //////////////////////////////////////////// if((set_level==3)&&(dif_level<=0)) { PORTC |= 0x02;; } else if((set_level==4)&&(dif_level<=0)) { PORTC |= 0x01; } else{ } } else { sei(); } PORTD = anaout[ana]; } return 0; }
void Hardware_init(void) { //PORTA is input //PORTB PORTC PORTD is output DDRA = 0x00; DDRB = 0xFF; DDRC = 0xFF; DDRD = 0xFF;
//clear PORT PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; }
void ADC_init(void) { //AVCC with external capacitor at AREF pin //ADMUX = (0 << REFS1)|(1 << REFS0);
//ADC Enable ADCSRA = (1 << ADEN);
//ADC Prescaler 8 ADCSRA |= (0 << ADPS2)|(1 << ADPS1)|(1 << ADPS0); }
void Timer1_init(void) { //Mode : CTC //TOP : OCR1A TCCR1A = (0 << WGM11)|(0 << WGM10); TCCR1B = (0 << WGM13)|(1 << WGM12);
//prescaler 8 TCCR1B |= (0 << CS12)|(1 << CS11)|(0 << CS10);
//8 MHz / 8 = 1 MHz //output compare interrupt is interval every 1 ms //1 MHz * 1 ms = 1000 clocks = 0x03E8 (in hex) OCR1AH = 0x01; OCR1AL = 0xF4; //Timer/Counter1 Output Compare A Match Interrupt Enable TIMSK = (1 << OCIE1A); }
ISR (TIMER1_COMPA_vect) { int k; for(k=0; k { if(TmrEnb[k] == 1) { TmrCnt[k]--; if(TmrCnt[k] == 0) { if(TmrRdy[k] == 1) { TmrErr[k] = 0; } else { TmrRdy[k] = 1; TmrCnt[k] = TmrRel[k]; if(TmrMod[k] == 0) { TmrEnb[k]=0; } } } } } }
back to circuit & code
|